package com.luck.picture.lib.tools;

import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.net.Uri;
import android.provider.MediaStore.Images;
import android.util.Log;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class BitmapUtil {
    /**
     * Constants
     */
    private static final String CONTENT = "content";
    private static final String FILE = "file";

//    public static ImageOptions imageOptions = new ImageOptions.Builder().setCrop(false)//
//            .setImageScaleType(ImageView.ScaleType.FIT_XY)//
////            .setLoadingDrawableId(R.drawable.pic_empty_big)//
//            .setPlaceholderScaleType(ImageView.ScaleType.CENTER_CROP)//
////            .setFailureDrawableId(R.drawable.pic_empty_big)// 设置错误图片
//            .build();

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // 源图片的高度和宽度
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            // 计算出实际宽高和目标宽高的比率
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);
            // 选择宽和高中最小的比率作为inSampleSize的值，这样可以保证最终图片的宽和高
            // 一定都会大于等于目标的宽和高。
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        return inSampleSize;
    }


    /**
     * mImageView.setImageBitmap(decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100,
     * 100));
     */
    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {
        // 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }

    public static Bitmap drawable2Bitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        } else if (drawable instanceof NinePatchDrawable) {
            Bitmap bitmap =
                    Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
            Canvas canvas = new Canvas(bitmap);
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
            drawable.draw(canvas);
            return bitmap;
        } else {
            return null;
        }
    }

    /**
     * 压缩图片
     *
     * @param context
     * @param srcPath 源文件地址
     * @return
     */
    public static Bitmap compressFile(Context context, String srcPath, String destPath) {
        Log.d("Bitmap/Debug", "***** BitmapUtil.compressFile called");
        Log.d("Bitmap/Debug", "***** srcPath:" + srcPath + ", destPath:" + destPath);
        float baseMult = 3f;

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeFile(srcPath, opts);
        int width = opts.outWidth;
        int height = opts.outHeight;
        Log.d("Bitmap/Debug", "***** " + opts.outWidth + " x " + opts.outHeight);

        float scale_w = (float) width / (float) ScreenUtils.getScreenWidth(context) * baseMult;
        float scale_h = (float) height / (float) ScreenUtils.getScreenHeight(context) * baseMult;
        Log.d("Bitmap/Debug", "***** scale_h:" + scale_h);
        Log.d("Bitmap/Debug", "***** scale_w:" + scale_w);
        float scale = scale_h > scale_w ? scale_w : scale_h;
        Log.d("Bitmap/Debug", "***** scale:" + scale);
        if (scale < 1) {
            scale = 1f;
        } else if (scale < 3) {
            scale = 2f;
        } else if (scale < 5) {
            scale = 4f;
        } else if (scale < 9) {
            scale = 8f;
        } else {
            scale = 16f;
        }
        Log.d("Bitmap/Debug", "***** inSampleSize:" + scale);
        opts.inSampleSize = (int) scale;
        opts.inJustDecodeBounds = false;
        bmp = BitmapFactory.decodeFile(srcPath, opts);
        Log.d("Bitmap/Debug", "***** " + opts.outWidth + " x " + opts.outHeight);
        saveBitmap(bmp, destPath);
        return bmp;
    }


    /**
     * 压缩图片
     *
     * @param filePath
     * @return
     */
    public static Bitmap compressFile(Context context, String filePath) {
        Log.d("Bitmap/Debug", "***** BitmapUtil.compressFile called");
        Log.d("Bitmap/Debug", "***** filePath:" + filePath);
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeFile(filePath, opts);
        float scale_h = (float) opts.outHeight / (float) ScreenUtils.getScreenHeight(context);
        float scale_w = (float) opts.outWidth / (float) ScreenUtils.getScreenWidth(context);
        Log.d("Bitmap/Debug", "***** scale_h:" + scale_h);
        Log.d("Bitmap/Debug", "***** scale_w:" + scale_w);
        float scale = scale_h > scale_w ? scale_w : scale_h;
        Log.d("Bitmap/Debug", "***** scale:" + scale);
        if (scale < 1) {
            scale = 1f;
        } else if (scale < 2) {
            scale = 2f;
        } else if (scale < 4) {
            scale = 4f;
        } else if (scale < 8) {
            scale = 8f;
        } else {
            scale = 16f;
        }
        Log.d("Bitmap/Debug", "***** inSampleSize:" + scale);
        opts.inSampleSize = (int) scale;
        opts.inJustDecodeBounds = false;
        bmp = BitmapFactory.decodeFile(filePath, opts);
        return bmp;
    }

    // public static Bitmap compressResource(Context context, Resources res, int id) {
    // LogUtil.d("Bitmap/Debug", "***** BitmapUtil.compressResource called");
    // BitmapFactory.Options opts = new BitmapFactory.Options();
    // opts.inJustDecodeBounds = true;
    // Bitmap bmp = BitmapFactory.decodeResource(res, id, opts);
    // float scale_h = (float) opts.outHeight / (float) ScreenUtils.getScreenHeight(context);
    // float scale_w = (float) opts.outWidth / (float) ScreenUtils.getScreenWidth(context);
    // LogUtil.d("Bitmap/Debug", "***** scale_h:" + scale_h);
    // LogUtil.d("Bitmap/Debug", "***** scale_w:" + scale_w);
    // float scale = scale_h > scale_w ? scale_w : scale_h;
    // LogUtil.d("Bitmap/Debug", "***** scale:" + scale);
    // if (scale < 1) {
    // scale = 1f;
    // } else if (scale < 2) {
    // scale = 2f;
    // } else if (scale < 4) {
    // scale = 4f;
    // } else if (scale < 8) {
    // scale = 8f;
    // } else {
    // scale = 16f;
    // }
    // LogUtil.d("Bitmap/Debug", "***** inSampleSize:" + scale);
    // opts.inSampleSize = (int) scale;
    // opts.inJustDecodeBounds = false;
    // bmp = BitmapFactory.decodeResource(res, id, opts);
    //
    // return bmp;
    // }

    /**
     * 获取文件的路径
     *
     * @param
     * @return
     */
    public static String getFilePath(Context context, Uri uri) {
        String filePath = null;
        if (CONTENT.equalsIgnoreCase(uri.getScheme())) {
            Cursor cursor = context.getContentResolver().query(uri, new String[]{Images.Media.DATA}, null, null, null);
            if (null == cursor) {
                return null;
            }
            try {
                if (cursor.moveToNext()) {
                    filePath = cursor.getString(cursor.getColumnIndex(Images.Media.DATA));
                }
            } finally {
                cursor.close();
            }
        }

        // 从文件中选择
        if (FILE.equalsIgnoreCase(uri.getScheme())) {
            filePath = uri.getPath();
        }
        return filePath;
    }

    /**
     * 以最省内存的方式读取本地资源的图片
     *
     * @param context
     * @param resId
     * @return
     */
    public static Bitmap readBitMap(Context context, int resId) {
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inPreferredConfig = Bitmap.Config.RGB_565;
        opt.inPurgeable = true;
        opt.inInputShareable = true;
        // 获取资源图片
        InputStream is = context.getResources().openRawResource(resId);
        return BitmapFactory.decodeStream(is, null, opt);
    }

    /**
     * @param bm
     * @param quality 压缩级别0-100 100表示不压缩
     * @return
     */
    public static Bitmap compressImage(Bitmap bm, int quality) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, quality, baos);// 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        // 压缩后大小 kb
        // int size = baos.toByteArray().length / 1024;

        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

    public static Bitmap zoomByScreenSize(Context context, Bitmap sourceBitmap, float scale) {
        float maxWidth = ScreenUtils.getScreenWidth(context) * scale;
        float maxHeight = ScreenUtils.getScreenHeight(context) * scale;
        // 获取这个图片的宽和高
        int width = sourceBitmap.getWidth();
        int height = sourceBitmap.getHeight();
        if (width > maxWidth && height > maxHeight) {
            // 创建操作图片用的matrix对象
            Matrix matrix = new Matrix();
            float scaleWidth = maxWidth / width;
            float scaleHeight = maxHeight / height;
            if (scaleWidth > scaleHeight) {
                matrix.postScale(scaleWidth, scaleWidth);
            } else {
                matrix.postScale(scaleHeight, scaleHeight);
            }
            // 缩放图片动作
            Bitmap bitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, (int) width, (int) height, matrix, true);
            return bitmap;
        }
        return sourceBitmap;
    }

    /**
     * 保存Bitmap到SDCard
     *
     * @param bitmap
     * @param filePath 图片保存路径
     */
    public static boolean saveBitmap(Bitmap bitmap, String filePath) {
        boolean success;
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
            success = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            success = false;
        } catch (IOException e) {
            e.printStackTrace();
            success = false;
        }
        return success;
    }

    /**
     * 保存Bitmap到SDCard
     *
     * @param bitmap
     */
    public static boolean saveBitmap(Bitmap bitmap, String filePath, double avatarSize) {
        boolean success;
        bitmap = zoomImage(bitmap, avatarSize, avatarSize);
        File file = new File(filePath);
        if (file.exists()) {
            file.delete();
        }
        try {
            FileOutputStream out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
            success = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            success = false;
        } catch (IOException e) {
            e.printStackTrace();
            success = false;
        }
        return success;
    }

    /**
     * 将图片缩放到指定尺寸
     *
     * @param sourceBitmap 图片源
     * @param newWidth     新的宽度
     * @param newHeight    新的高度
     * @return
     */
    public static Bitmap zoomImage(Bitmap sourceBitmap, double newWidth, double newHeight) {
        // 获取这个图片的宽和高
        float width = sourceBitmap.getWidth();
        float height = sourceBitmap.getHeight();
        // 创建操作图片用的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, (int) width, (int) height, matrix, true);
        return bitmap;
    }

    /**
     * 获取SD卡中的图片
     *
     * @param pathString
     * @return
     */
    public static Bitmap getDiskBitmap(String pathString) {
        Bitmap bitmap = null;
        try {
            File file = new File(pathString);
            if (file.exists()) {
                bitmap = BitmapFactory.decodeFile(pathString);
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        return bitmap;
    }

    public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap oldbmp = drawableToBitmap(drawable); // drawable 转换成 bitmap
        Matrix matrix = new Matrix();   // 创建操作图片用的 Matrix 对象
        float scaleWidth = ((float) w / width);   // 计算缩放比例
        float scaleHeight = ((float) h / height);
        float scal = 1.0f;
        if (scaleWidth > scaleHeight) {
            scal = scaleWidth;
        } else {
            scal = scaleHeight;
        }
        matrix.postScale(scal, scal);         // 设置缩放比例
        Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);       // 建立新的 bitmap ，其内容是对原 bitmap 的缩放后的图
        return new BitmapDrawable(newbmp);       // 把 bitmap 转换成 drawable 并返回
    }

    public static Bitmap drawableToBitmap(Drawable drawable) // drawable 转换成 bitmap
    {
        int width = drawable.getIntrinsicWidth();   // 取 drawable 的长宽
        int height = drawable.getIntrinsicHeight();
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;         // 取 drawable 的颜色格式
        Bitmap bitmap = Bitmap.createBitmap(width, height, config);     // 建立对应 bitmap
        Canvas canvas = new Canvas(bitmap);         // 建立对应 bitmap 的画布
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);      // 把 drawable 内容画到画布中
        return bitmap;
    }

}
